/********************************************************************
	filename: 	GeoAlgorithm.h
	created:	2010/04/16
	author:		Xiuwei Chen

	purpose:	Define the function of 2D geometry algorithm

	All rights Reserved
*********************************************************************/

#pragma  once
#include "Const.h"
#include "Vector2D.h"
#include "Segment2D.h"
#include "Line2D.h"
#include "Rectangle2D.h"
#include "Triangle2D.h"
#include "Trilinear.h"

/************************************************************************/
/* Equal                                                                */
/************************************************************************/

/// <Summary>
/// check if two numbers are equal
/// </Summary>
GEOMETRY_EXPORT bool Equal(double a, double b);

/// <Summary>
/// check if two 2D Points are equal
/// </Summary>
GEOMETRY_EXPORT bool Equal(const Point2D &p1, const Point2D &p2);

/// <Summary>
/// check if two 2D lines are equal
/// </Summary>
GEOMETRY_EXPORT bool Equal(const Line2D &line0, const Line2D &line1);

/// <Summary>
/// check if two 2D segments are equal
/// </Summary>
GEOMETRY_EXPORT bool Equal(const Segment2D &seg0, const Segment2D &seg1);

/// <Summary>
/// check if two 2D rectangles are equal
/// </Summary>
GEOMETRY_EXPORT bool Equal(const Rectangle2D &rect0, const Rectangle2D &rect1);

/************************************************************************/
/* Distance                                                             */
/************************************************************************/
/// <Summary>
/// distance square of two 2D point
/// </Summary>
GEOMETRY_EXPORT double DistanceSquare(const Point2D &p1, const Point2D &p2);

/// <Summary>
/// distance of tow 2D point
/// </Summary>
GEOMETRY_EXPORT double Distance(const Point2D &p1, const Point2D &p2);

/// <Summary>
/// distance between 2D point and 2D line
/// </Summary>
GEOMETRY_EXPORT double Distance(const Point2D &p, const Line2D &line);

/// <Summary>
/// distance between two 2D line [EP]
/// </Summary>
GEOMETRY_EXPORT double Distance(const Line2D &line0, const Line2D &line1);

/// <Summary>
/// distance between 2D point and 2D segment
/// </Summary>
GEOMETRY_EXPORT double Distance(const Point2D &p, const Segment2D &seg);

/// <Summary>
/// distance between two 2D segment
/// </Summary>
GEOMETRY_EXPORT double Distance(const Segment2D &seg0, const Segment2D &seg1);

/// <Summary>
/// distance between a point and a rectangle
/// </Summary>
GEOMETRY_EXPORT double Distance(const Point2D &p, const Rectangle2D &rect);

/// <Summary>
/// distance between two rectangles
/// </Summary>
GEOMETRY_EXPORT double Distance(const Rectangle2D &rect0, const Rectangle2D &rect1);

/************************************************************************/
/* CrossProduct and DotProduct                                          */
/************************************************************************/

/// <Summary>
/// cross product of two 2D vector
/// result < 0: v1 lie counter clockwise of v2
/// result = 0: v1 and v2 lie in a line by the same direction or right-about
/// reuslt > 0: v1 lie clockwise of v2
/// </Summary>
GEOMETRY_EXPORT double CrossProduct(const Vector2D &v1, const Vector2D &v2);

/// <Summary>
/// cross product of two 2D vector: (p1 - p0) and (p2 - p0)
/// </Summary>
GEOMETRY_EXPORT double CrossProduct(const Point2D &p0, const Point2D &p1, const Point2D &p2);

/// <Summary>
/// cross product of two 2D vector
/// </Summary>
GEOMETRY_EXPORT double DotProduct(const Vector2D &v1, const Vector2D &v2);

/// <Summary>
/// cross product of two 2D vector: (p1 - p0) and (p2 - p0)
/// </Summary>
GEOMETRY_EXPORT double DotProduct(const Point2D &p0, const Point2D &p1, const Point2D &p2);


/************************************************************************/
/* Angle                                                                */
/************************************************************************/

/// <Summary>
/// the angle between two 2D line: [0, PI / 2]
/// </Summary>
GEOMETRY_EXPORT double Angle(const Line2D &line0, const Line2D &line1);

/// <Summary>
/// the counter clockwise angle from 2D vector v0 to v1: [-PI, PI)
/// </Summary>
GEOMETRY_EXPORT double Angle(const Vector2D &v0, const Vector2D &v1);


/************************************************************************/
/* Symmetry                                                             */
/************************************************************************/

/// <Summary>
/// get 2D point's symmetry point about a 2D point
/// </Summary>
GEOMETRY_EXPORT Point2D Symmetry(const Point2D &p, const Point2D &origin);

/// <Summary>
/// get 2D point's symmetry point about a 2D line
/// </Summary>
GEOMETRY_EXPORT Point2D Symmetry(const Point2D &p, const Line2D &line);

/// <Summary>
/// get 2D line's symmetry line about a 2D point
/// </Summary>
GEOMETRY_EXPORT Line2D Symmetry(const Line2D &line, const Point2D &p);


/************************************************************************/
/* Center                                                               */
/************************************************************************/

/// <Summary>
/// center of two 2D point
/// </Summary>
GEOMETRY_EXPORT Point2D Center(const Point2D &p0, const Point2D &p1);

/// <Summary>
/// center of a 2D segment
/// </Summary>
GEOMETRY_EXPORT Point2D Center(const Segment2D &seg);

/// <Summary>
/// center of 2D rectangle
/// </Summary>
GEOMETRY_EXPORT Point2D Center(const Rectangle2D &rect);

/************************************************************************/
/* Perpendicular and Parallel                                           */
/************************************************************************/

/// <Summary>
/// get the Perpendicular of 2D line which pass by a point
/// </Summary>
GEOMETRY_EXPORT Line2D Perpendicular(const Line2D &line, const Point2D &p);

/// <Summary>
/// check if two 2D lines are parallel [EP]
/// </Summary>
GEOMETRY_EXPORT bool Parallel(const Line2D &line0, const Line2D &line1);


/************************************************************************/
/* Nearest Point                                                        */
/************************************************************************/

/// <Summary>
/// get 2D point's nearest point on a 2D line (foot of a Perpendicular)
/// </Summary>
GEOMETRY_EXPORT Point2D Nearest(const Point2D &p, const Line2D &line);

/// <Summary>
/// get 2D point's nearest point on a 2D segment
/// </Summary>
GEOMETRY_EXPORT Point2D Nearest(const Point2D &p, const Segment2D &seg);

/// <Summary>
/// get 2D point's nearest point on a 2D rectangle
/// </Summary>
GEOMETRY_EXPORT Point2D Nearest(const Point2D &p, const Rectangle2D &rect);


/************************************************************************/
/* Inside                                                               */
/************************************************************************/

/// <Summary>
/// check if 2D point is inside the 2D line [EP]
/// </Summary>
GEOMETRY_EXPORT bool Inside(const Point2D &p, const Line2D &line, bool bound = true);

/// <Summary>
/// check if 2D point is inside the 2D segment [EP]
/// </Summary>
GEOMETRY_EXPORT bool Inside(const Point2D &p, const Segment2D &seg, bool bound = true);

/// <Summary>
/// check if 2D point is inside the 2D rectangle
/// </Summary>
GEOMETRY_EXPORT bool Inside(const Point2D &p, const Rectangle2D &rect, bool bound = true);


/************************************************************************/
/* Intersect                                                            */
/************************************************************************/

/// <Summary>
/// check if two 2D lines are intersect, get the intersect point if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Line2D &line0, const Line2D &line1, Point2D *point = NULL);

/// <Summary>
/// check if two 2D segments are intersect, get the intersect point if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Segment2D &seg0, const Segment2D &seg1, Point2D *point = NULL);

/// <Summary>
/// check if 2D segments and 2D line are intersect, get the intersect point if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Segment2D &seg, const Line2D &line, Point2D *point = NULL);

/// <Summary>
/// check if two 2D rectangle are intersect, get the intersect rectangle if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Rectangle2D &rect0, const Rectangle2D &rect1, Rectangle2D *rect = NULL);

/// <Summary>
/// check if 2D rectangle and 2D line are intersect, get the intersect segment if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Line2D &line, const Rectangle2D &rect, Segment2D *segment = NULL);

/// <Summary>
/// check if 2D rectangle and 2D segment are intersect, get the intersect segment if yes.
/// </Summary>
GEOMETRY_EXPORT bool Intersect(const Segment2D &seg, const Rectangle2D &rect, Segment2D *segment = NULL);

/************************************************************************/
/* Translation                                                          */
/************************************************************************/
/// <Summary>
/// 2D Point's Translation
/// </Summary>
GEOMETRY_EXPORT Point2D Translation(const Point2D &point, const Vector2D &v);

/// <Summary>
/// 2D Segment's Translation
/// </Summary>
GEOMETRY_EXPORT Segment2D Translation(const Segment2D &seg, const Vector2D &v);

/// <Summary>
/// 2D Segment's Translation
/// </Summary>
GEOMETRY_EXPORT Segment2D Translation(const Segment2D &seg, const Vector2D &v0, const Vector2D &v1);

/// <Summary>
/// 2D line's Translation
/// </Summary>
GEOMETRY_EXPORT Line2D Translation(const Line2D &line, const Vector2D &v);

/************************************************************************/
/* Rotation                                                             */
/************************************************************************/
/// <Summary>
/// rotate 2D point counter clockwise around a center point (radian)
/// </Summary>
GEOMETRY_EXPORT Point2D Rotation(const Point2D &p, const Point2D &center, double angle);

/// <Summary>
/// rotate 2D segment counter clockwise around a center point (radian)
/// </Summary>
GEOMETRY_EXPORT Segment2D Rotation(const Segment2D &seg, const Point2D &center, double angle);

/// <Summary>
/// rotate 2D line counter clockwise around a center point (radian)
/// </Summary>
GEOMETRY_EXPORT Line2D Rotation(const Line2D &line, const Point2D &center, double angle);

/// <Summary>
/// rotate 2D triangle counter clockwise around a center point (radian)
/// </Summary>
GEOMETRY_EXPORT Triangle2D Rotation(const Triangle2D &triangle, const Point2D &center, double angle);

/************************************************************************/
/* Merge                                                                */
/************************************************************************/
/// <Summary>
/// merge two rectangle
/// </Summary>
GEOMETRY_EXPORT Rectangle2D Merge(const Rectangle2D &rect0, const Rectangle2D &rect1);


/************************************************************************/
/* Convert                                                              */
/************************************************************************/
/// <Summary>
/// from 2D point to trilinear coordinate
/// </Summary>
GEOMETRY_EXPORT void Convert(const Point2D &point, const Triangle2D &triangle, Trilinear &triCoord);

/// <Summary>
/// from trilinear coordinate to 2D point
/// </Summary>
GEOMETRY_EXPORT void Convert(const Trilinear &triCoord, const Triangle2D &triangle, Point2D &point);